package com.example.xcService.pojo.channels.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.*;
import java.util.regex.Pattern;
/**
 * 美团官方接口
 * **/
@Slf4j
public class Plugin_ECARD_P001 implements ChannelService {
    public ChannelResult QueryBalance(JSONObject apiConfig){
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }
    public  ChannelResult Submit(JSONObject apiConfig, Map<String,Object> data){

       try {
           if ( Pattern.matches("^1[3456789]\\d{9}$",String.valueOf(data.get("AccountVal"))) == false)
           {
               return ChannelResult.FAILED("充值失败：手机号错误" );
           }
           Map<String,String> headers=new HashMap<>();
           String curTime=String.valueOf(System.currentTimeMillis());
           String orderTime = String.valueOf(System.currentTimeMillis()/1000);
           headers.put("S-Ca-App",apiConfig.getString("S-Ca-App"));
           headers.put("S-Ca-Timestamp",curTime);
           List<String> signHeaderPrefixList=new ArrayList<>();
           signHeaderPrefixList.add("S-Ca-App");
           signHeaderPrefixList.add("S-Ca-Timestamp");

           Map<String,Object> VpOffsiteSkuInfo=new HashMap<>();
           VpOffsiteSkuInfo.put("skuViewId",data.get("SUPProductId"));
           VpOffsiteSkuInfo.put("num",1);
           VpOffsiteSkuInfo.put("serviceProviderSkuOrderId",data.get("ChannelOrderCode"));
           VpOffsiteSkuInfo.put("originalSkuOrderId",data.get("ChannelOrderCode"));


           List<Map<String,Object>> skuList = new ArrayList<Map<String,Object>>();
           skuList.add(VpOffsiteSkuInfo);

           Map<String,Object> order=new HashMap<>();
           order.put("serviceProviderCode",apiConfig.get("USERID"));
           order.put("saleChannel", Integer.valueOf(String.valueOf(apiConfig.get("saleChannel"))));
           order.put("serviceProviderOrderId",data.get("ChannelOrderCode"));
           order.put("phone",data.get("AccountVal"));
           order.put("skuList",skuList);
           order.put("orderTime",Integer.valueOf(orderTime));
           order.put("orderSource",apiConfig.getString("S-Ca-App"));

           String body= JSONObject.toJSONString(order);
           String contentMD5 = new String(org.apache.commons.codec.binary.Base64.encodeBase64(stringToMD5(body.getBytes("UTF-8"))));
           String Headers=buildHeaders(headers,signHeaderPrefixList);

           String stringToSign= "POST" + "\n" + contentMD5 + "\n" + Headers + "/partner/coupon_package/sync_order_info_and_perform";
           String HeaderStr = "S-Ca-App,S-Ca-Timestamp";
           Mac hmacSha256 = Mac.getInstance("HmacSHA256");
           byte[] keyBytes = apiConfig.getString("SecretKey").getBytes("UTF-8");
           hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256"));

           String sign=new  String(org.apache.commons.codec.binary.Base64.encodeBase64(
                   hmacSha256.doFinal(stringToSign
                           .getBytes("UTF-8"))),
                   "UTF-8");

           headers.put("S-Ca-Signature",sign);
           headers.put("S-Ca-Signature-Headers",HeaderStr);
           headers.put("Content-MD5",contentMD5);

           String url=apiConfig.getString("SubmitURL");
           String res= sendPost(url,JSONObject.toJSONString(order),headers);
           JSONObject retobj = JSONObject.parseObject(res);
           String status=retobj.getString("code");
           if("0".equals(status)){
               JSONArray skus=retobj.getJSONArray("skuList");
               String code=skus.getObject(0,JSONObject.class).getString("status");
               if ("1".equals(code)){
                   return  ChannelResult.IN_PROCESS();
               } else if (!"-3".equals(status) && !"3".equals(status) && !"4".equals(status))
               {
                   return ChannelResult.FAILED("充值失败："+status);
               }

               return  ChannelResult.error(code);

           }else  if ("201".equals(status)){
               return ChannelResult.FAILED("充值失败："+status);
           }else {
             return ChannelResult.error(status);
           }
       }catch (Exception ex){
           ex.printStackTrace();
           log.error("美团提交订单接口错误：",ex);
           return  ChannelResult.error("美团提交订单接口错误");
       }

    }
    public  ChannelResult Query(JSONObject apiConfig,Map<String,Object> data) {
        try {



            Map<String, String> headers = new HashMap<>();
            String curTime = String.valueOf(System.currentTimeMillis());
            headers.put("S-Ca-App", apiConfig.getString("S-Ca-App"));
            headers.put("S-Ca-Timestamp", curTime);
            List<String> signHeaderPrefixList = new ArrayList<>();
            signHeaderPrefixList.add("S-Ca-App");
            signHeaderPrefixList.add("S-Ca-Timestamp");


            Map<String, Object> order = new HashMap<>();
            order.put("serviceProviderCode", apiConfig.get("USERID"));
            order.put("saleChannel", Integer.valueOf(String.valueOf(apiConfig.get("saleChannel"))));
            order.put("serviceProviderOrderId", data.get("ChannelOrderCode"));
            order.put("phone", data.get("AccountVal"));

            String body = JSONObject.toJSONString(order);
            String contentMD5 = new String(org.apache.commons.codec.binary.Base64.encodeBase64(stringToMD5(body.getBytes("UTF-8"))));
            String Headers = buildHeaders(headers, signHeaderPrefixList);

            String stringToSign = "POST" + "\n" + contentMD5 + "\n" + Headers + "/partner/coupon_package/get_perform_status";
            String HeaderStr = "S-Ca-App,S-Ca-Timestamp";
            Mac hmacSha256 = Mac.getInstance("HmacSHA256");
            byte[] keyBytes = apiConfig.getString("SecretKey").getBytes("UTF-8");
            hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256"));

            String sign = new String(org.apache.commons.codec.binary.Base64.encodeBase64(
                    hmacSha256.doFinal(stringToSign
                            .getBytes("UTF-8"))),
                    "UTF-8");

            headers.put("S-Ca-Signature", sign);
            headers.put("S-Ca-Signature-Headers", HeaderStr);
            headers.put("Content-MD5", contentMD5);

            String url = apiConfig.getString("QueryURL");
            String res = sendPost(url, JSONObject.toJSONString(order), headers);
            JSONObject retobj = JSONObject.parseObject(res);
            String status = retobj.getString("code");
            if ("0".equals(status)) {
                JSONArray skus = retobj.getJSONArray("skuList");
                String code = skus.getObject(0, JSONObject.class).getString("status");
                if ("2".equals(code)) {
                    return ChannelResult.success("充值成功");
                } else if ("6".equals(status)) {
                    return ChannelResult.FAILED("充值失败：" + status);
                }
                return  ChannelResult.error(code);

            }else if ("201".equals(status) || "103".equals(status)){
                return ChannelResult.FAILED(status);
            }
            else {
                return ChannelResult.error(status);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("美团查询订单接口错误：", ex);
            return ChannelResult.error("美团查询订单接口错误");
        }
    }


    public  ChannelResult Notify(JSONObject apiConfig,Map<String,Object> data){
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");

    }

    public static String sendPost(String url, String param,Map<String,String> header) {
        String result = "";
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        // 创建Post请求
        HttpPost httpPost = new HttpPost(url);
        String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36";
        httpPost.setHeader("User-Agent",userAgent);

        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
            httpPost.setHeader("Content-Type", "application/json;charset=utf8");
            httpPost.setHeader("S-Ca-App","offsite_jianuo_online_app");
            httpPost.setHeader("S-Ca-Timestamp",header.get("S-Ca-Timestamp"));
            httpPost.setHeader("S-Ca-Signature",header.get("S-Ca-Signature"));
            httpPost.setHeader("S-Ca-Signature-Headers",header.get("S-Ca-Signature-Headers"));
            httpPost.setHeader("Content-MD5",header.get("Content-MD5"));
            httpPost.setEntity(new StringEntity(param));
            log.info("httpPost请求："+url+"?"+param);
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                result= EntityUtils.toString(responseEntity);
                log.info("httpPost请求返回："+JSONObject.toJSONString(result));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  result;
    }


    public static byte[] stringToMD5(byte[] plainText) throws Exception{
        byte[] secretBytes = null;
        StringBuilder md5code = new StringBuilder();
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    plainText);

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return secretBytes;
    }

    private static String buildHeaders(Map<String, String> headers, List<String> signHeaderPrefixList) {
        StringBuilder sb = new StringBuilder();

        if (null != signHeaderPrefixList) {

            Collections.sort(signHeaderPrefixList);
            if (null != headers) {
                Map<String, String> sortMap = new TreeMap<String, String>();
                sortMap.putAll(headers);
                StringBuilder signHeadersStringBuilder = new StringBuilder();
                for (Map.Entry<String, String> header : sortMap.entrySet()) {
                    sb.append(header.getKey());
                    sb.append(":");
                    sb.append(header.getValue());
                    sb.append("\n");
                    if (0 < signHeadersStringBuilder.length()) {
                        signHeadersStringBuilder.append(",");
                    }
                    signHeadersStringBuilder.append(header.getKey());
                }
                headers.put("S-Ca-Signature-Headers", signHeadersStringBuilder.toString());
            }
        }

        return sb.toString();
    }
}
